package com.lyq.bean.service;

import com.lyq.bean.Course;
import com.lyq.bean.Student;
import java.util.*;

public class RecommendationService {
    
    /**
     * 根据学生培养方案和偏好推荐课程
     * @param allCourses 所有课程列表
     * @param student 学生对象
     * @param preferences 学生偏好设置
     * @return 推荐课程列表
     */
    public List<Course> recommendCourses(List<Course> allCourses, Student student, Map<String, String> preferences) {
        List<Course> recommendedCourses = new ArrayList<>();
        
        // 获取学生已选课程
        E_Service eService = new E_Service();
        List<Course> electedCourses = eService.seek_ElectC(student.getNo());
        
        // 获取学生专业和培养方案信息
        String department = student.getDepartment();
        String interest = preferences.get("interest");
        String career = preferences.get("career");
        String courseType = preferences.get("courseType");
        String creditLoad = preferences.get("creditLoad");
        
        // 根据学术能力与历史表现推荐
        List<Course> academicBasedCourses = recommendByAcademicPerformance(allCourses, student, electedCourses);
        
        // 根据个人兴趣和职业规划推荐
        List<Course> interestBasedCourses = recommendByInterestAndCareer(allCourses, interest, career);
        
        // 合并推荐结果
        Set<Course> mergedCourses = new HashSet<>();
        mergedCourses.addAll(academicBasedCourses);
        mergedCourses.addAll(interestBasedCourses);
        
        recommendedCourses.addAll(mergedCourses);
        
        // 根据课程类型偏好筛选
        if (courseType != null && !courseType.isEmpty() && !courseType.equals("不限")) {
            recommendedCourses.removeIf(course -> !courseType.equals(course.getCourseType()));
        }
        
        // 根据学分负荷筛选
        if (creditLoad != null && !creditLoad.isEmpty() && !creditLoad.equals("不限")) {
            recommendedCourses.removeIf(course -> !matchesCreditLoad(course, creditLoad));
        }
        
        // 按优先级排序（专业必修课 > 专业选修课 > 公共必修课 > 公共选修课）
        recommendedCourses.sort((c1, c2) -> {
            int priority1 = getCoursePriority(c1, department);
            int priority2 = getCoursePriority(c2, department);
            return Integer.compare(priority1, priority2);
        });
        
        return recommendedCourses;
    }
    
    /**
     * 根据学术能力与历史表现推荐课程
     */
    private List<Course> recommendByAcademicPerformance(List<Course> allCourses, Student student, List<Course> electedCourses) {
        List<Course> recommended = new ArrayList<>();
        
        // 获取学生专业
        String department = student.getDepartment();
        
        // 统计已选课程的类别和学分
        Map<String, Double> categoryCredits = calculateCategoryCredits(electedCourses);
        
        // 推荐尚未满足学分要求的课程类别
        for (Course course : allCourses) {
            String category = course.getCategory();
            // 只处理有类别的课程
            if (category != null && !category.isEmpty()) {
                double currentCredits = categoryCredits.getOrDefault(category, 0.0);
                // 如果该类别学分未达到要求，则推荐该类别的课程
                // 假设每类需要2学分
                if (currentCredits < 2.0) {
                    recommended.add(course);
                }
            }
        }
        
        return recommended;
    }
    
    /**
     * 根据个人兴趣和职业规划推荐课程
     */
    private List<Course> recommendByInterestAndCareer(List<Course> allCourses, String interest, String career) {
        List<Course> recommended = new ArrayList<>();
        
        for (Course course : allCourses) {
            boolean shouldRecommend = false;
            
            // 根据兴趣方向推荐
            if (interest != null && !interest.isEmpty()) {
                if (interest.equals("技术") && "科学".equals(course.getCategory())) {
                    shouldRecommend = true;
                } else if (interest.equals("管理") && "人文".equals(course.getCategory())) {
                    shouldRecommend = true;
                } else if (interest.equals("艺术") && "艺术".equals(course.getCategory())) {
                    shouldRecommend = true;
                } else if (interest.equals("科学") && "科学".equals(course.getCategory())) {
                    shouldRecommend = true;
                }
            }
            
            // 根据职业规划推荐
            if (career != null && !career.isEmpty()) {
                if (career.equals("工程师") && "科学".equals(course.getCategory())) {
                    shouldRecommend = true;
                } else if (career.equals("设计师") && "艺术".equals(course.getCategory())) {
                    shouldRecommend = true;
                } else if (career.equals("研究员") && "科学".equals(course.getCategory())) {
                    shouldRecommend = true;
                }
            }
            
            if (shouldRecommend) {
                recommended.add(course);
            }
        }
        
        return recommended;
    }
    
    /**
     * 检查课程是否符合学分负荷要求
     */
    private boolean matchesCreditLoad(Course course, String creditLoad) {
        try {
            double credit = Double.parseDouble(course.getCredit());
            switch (creditLoad) {
                case "低":
                    return credit >= 1 && credit <= 3;
                case "中":
                    return credit >= 4 && credit <= 6;
                case "高":
                    return credit >= 7;
                default:
                    return true;
            }
        } catch (NumberFormatException e) {
            return true; // 无法解析学分时默认包含
        }
    }
    
    /**
     * 获取课程优先级（数字越小优先级越高）
     * 专业必修课(1) > 专业选修课(2) > 公共必修课(3) > 公共选修课(4)
     */
    private int getCoursePriority(Course course, String department) {
        String classification = course.getCourseClassification();
        
        // 根据course_classification字段直接判断课程类型
        switch (classification) {
            case "专业必修课":
                return 1;
            case "专业选修课":
                return 2;
            case "公共必修课":
                return 3;
            case "公共选修课":
                return 4;
            default:
                return 5; // 未分类课程
        }
    }
    
    /**
     * 生成针对特定学生的课程推荐理由
     * @param course 被推荐的课程
     * @param student 学生对象
     * @param electedCourses 学生已选课程列表
     * @return 推荐理由
     */
    public String generateRecommendationReason(Course course, Student student, List<Course> electedCourses) {
        List<String> reasons = new ArrayList<>();
        
        // 基于专业匹配的推荐理由
        if (course.getCourseClassification().contains("专业")) {
            if (student.getDepartment() != null && course.getNo().startsWith(student.getDepartment())) {
                reasons.add("与您的专业(" + student.getDepartment() + ")高度相关");
            }
        }
        
        // 基于必修要求的推荐理由
        if (course.getCourseClassification().contains("必修")) {
            reasons.add("属于必修课程，需要修读以满足毕业要求");
        }
        
        // 基于学分要求的推荐理由
        if (course.getCategory() != null && !course.getCategory().isEmpty()) {
            Map<String, Double> categoryCredits = calculateCategoryCredits(electedCourses);
            double currentCredits = categoryCredits.getOrDefault(course.getCategory(), 0.0);
            if (currentCredits < 2.0) { // 假设每类需要2学分
                reasons.add("您在" + course.getCategory() + "类别中学分不足(当前" + String.format("%.1f", currentCredits) + "学分)，该课程可帮助您满足学分要求");
            }
        }
        
        // 基于兴趣匹配的推荐理由
        if (course.getCategory() != null && !course.getCategory().isEmpty()) {
            reasons.add("与您选择的课程类别(" + course.getCategory() + ")相符");
        }
        
        // 基于GPA的推荐理由
        if (student.getGpa() >= 3.0) {
            reasons.add("您的GPA较高(" + String.format("%.2f", student.getGpa()) + ")，适合挑战该课程");
        } else if (student.getGpa() < 2.0) {
            reasons.add("根据您的学术表现，该课程难度适中，适合您当前水平");
        }
        
        // 如果没有特定原因，提供通用推荐理由
        if (reasons.isEmpty()) {
            reasons.add("根据您的培养方案和选课历史推荐此课程");
        }
        
        return String.join("；", reasons);
    }
    
    /**
     * 计算学生在各个类别中已获得的学分
     * @param electedCourses 已选课程列表
     * @return 各类别已获得的学分映射
     */
    private Map<String, Double> calculateCategoryCredits(List<Course> electedCourses) {
        Map<String, Double> categoryCredits = new HashMap<>();
        for (Course course : electedCourses) {
            String category = course.getCategory();
            if (category != null && !category.isEmpty()) {
                double credit = 0.0;
                try {
                    credit = Double.parseDouble(course.getCredit());
                } catch (NumberFormatException e) {
                    // 忽略无法解析的学分
                }
                
                categoryCredits.put(category, categoryCredits.getOrDefault(category, 0.0) + credit);
            }
        }
        return categoryCredits;
    }
    
    /**
     * 检查学生是否满足课程的先修要求
     * @param course 目标课程
     * @param electedCourses 已选课程列表
     * @return 是否满足先修要求
     */
    public boolean checkPrerequisites(Course course, List<Course> electedCourses) {
        // 简化实现：这里可以扩展为更复杂的先修课程检查逻辑
        // 例如检查是否已完成某些特定课程
        
        // 对于必修课程，通常需要确保没有时间冲突且符合学期要求
        return true;
    }
    
    /**
     * 生成学生的培养方案进度报告
     * @param student 学生对象
     * @param electedCourses 已选课程列表
     * @return 进度报告
     */
    public Map<String, Object> generateProgressReport(Student student, List<Course> electedCourses) {
        Map<String, Object> report = new HashMap<>();
        
        // 按类别统计已修学分
        Map<String, Double> categoryCredits = calculateCategoryCredits(electedCourses);
        double totalCredits = 0.0;
        
        for (Double credits : categoryCredits.values()) {
            totalCredits += credits;
        }
        
        report.put("categoryCredits", categoryCredits);
        report.put("totalCredits", totalCredits);
        report.put("gpa", student.getGpa());
        
        return report;
    }
}